package net.alche.al.util.far;

import java.util.Map;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import net.alche.al.util.AC;
import net.alche.al.util.Far;
import net.alche.fa.core.FaClass;
import net.alche.fa.core.FaException;
import net.alche.fa.core.FaUtil;
import net.alche.fa.core.SageStone;
import net.alche.fa.core.model.FaValue;

import java.lang.reflect.Field;

// FaBaseJava
@SuppressWarnings("all")
public class FaBaseJava {

  public FaBaseJava() {
  }

  public Map<String, Object> getMap(String keys, Object... objs) {
    Map<String, Object> map = new HashMap<>();
    if (Far.tl.noEmpty(keys) && Far.tl.notEmpty(objs)) {
      String[] sp = keys.split(",");
      for (int i = 0; i < sp.length; i++) {
        map.put(sp[i], objs[i]);
      }
    }
    return map;
  }

  public Object getAttr(Object obj, String colName) {
    if (obj == null) {
      return null;
    }
    try {
      Field fi = obj.getClass().getField(colName);
      return fi.get(obj);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  public void setAttr(Object obj, String colName, Object val) {
    if (obj == null) {
      return;
    }
    try {
      Field fi = obj.getClass().getField(colName);
      fi.set(obj, val);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public FaValue parseJson(String json, FaClass clas) {
    FaValue fav = new FaValue();
    Map<String, Object> mp = Far.tl.fromJsonMap(json);
    try {
      return FaUtil.mapToPojoDeep(clas.instance(null), mp);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return null;
  }

  public FaValue parseJsonList(String json, FaClass clas) {
    FaValue fav = new FaValue();
    List<Map> mpList = Far.tl.getMapList(json);
    if (mpList != null) {
      List ls = new ArrayList();
      try {
        for (Map mp : mpList) {
          FaValue itemVal = FaUtil.mapToPojoDeep(clas.instance(null), mp);
          ls.add(itemVal);
        }
      } catch (FaException e) {
        e.printStackTrace();
      }
      fav.setType(FaValue._LIST);
      fav.aiData(ls);
      return fav;
    }
    return null;
  }

  public FaValue copyCols(SageStone source, String[] cols) {
    if (source == null)
      return null;
    FaValue fav = new FaValue();
    try {
      SageStone sage = source.getFaClass().instance();
      if (cols != null && cols.length > 0) {
        for (String col : cols) {
          FaValue attr = source.getVar(col);
          if (attr != null && attr.getValue() != null) {
            FaValue toAttr = sage.getVar(col);
            toAttr.giveValue(attr, sage.getPlat());
          }
        }
      }
      fav.aiData(sage);
    } catch (FaException e) {
      e.printStackTrace();
    }
    return fav;
  }

  public void fillByStr(SageStone obj, String spChar, String[] cols) {
    if (obj == null)
      return;
    if (cols != null && cols.length > 0 && spChar != null) {
      try {
        String[] sp = spChar.split("\\^\\|\\^");
        for (int i = 0; i < sp.length && i < cols.length; i++) {
          FaValue fd = obj.getVar(cols[i]);
          String str = sp[i];
          if (fd != null) {
            Object toVal = str;
            if (AC.notEmpty(str)) {
              if (fd.getType() == FaValue._INT) {
                toVal = Integer.parseInt(str);
              } else if (fd.getType() == FaValue._DOUBLE) {
                toVal = Double.parseDouble(str);
              } else if (fd.getType() == FaValue._LONG) {
                toVal = Long.parseLong(str);
              } else if (fd.getType() == FaValue._DATE) {
                toVal = AC.date.parse(str, null);
              }
            }
            fd.aiData(toVal);
          }
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public static Object checkFaValueObj(Object obj) {
    if (obj != null) {
      // fav
      if (obj instanceof FaValue fav)
        return fav.getJava();
      if (obj instanceof List ls) {
        if (!AC.empty(ls)) {
          Object firstChild = ls.get(0);
          // 2.fava-list
          if (firstChild instanceof FaValue) {
            List nls = new ArrayList<>();
            for (Object item : ls) {
              FaValue fav = (FaValue) item;
              nls.add(fav.getJava());
            }
            return nls;
          }
        }
      }
    }
    return obj;
  }
}